package book;

import constant.Constant;
import utils.AnalyzingBook;
import utils.AnalyzingBookIdMax;
import utils.AnalyzingBorrowedBook;
import utils.SingletonScanner;

import java.io.IOException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Scanner;

public class Library {
    private Book[] books;
    private int bookCount;
    private int bookIdMax;
    private int borrowCount;
    public Scanner scanner = SingletonScanner.getScanner();
    private static Library library = Library.getInstance();
    public AnalyzingBook analyzingBook = new AnalyzingBook();
    public AnalyzingBookIdMax analyzingBookIdMax = new AnalyzingBookIdMax();
    private PairOfUidAndBookId[] pairOfUidAndBookIds;
    private AnalyzingBorrowedBook analyzingBorrowedBook = new AnalyzingBorrowedBook();


    private Library(){
        loadBooks();
        loadMaxBookId();
        loadUidAndBookId();
    }

    public Book[] getBooks() {
        return books;
    }

    public void setBooks(Book[] books) {
        this.books = books;
    }

    public int getBookCount() {
        return bookCount;
    }

    public void setBookCount(int bookCount) {
        this.bookCount = bookCount;
    }

    private void increaseBookCount(){
        bookCount++;
    }

    private void decreaseBookCount(){
        bookCount--;
    }

    public int getBorrowCount() {
        return borrowCount;
    }

    public void setBorrowCount(int borrowCount) {
        this.borrowCount = borrowCount;
    }

    public void loadMaxBookId(){
        try {
            int idMaxTmp = analyzingBookIdMax.loadBookIdMax(Constant.BOOK_ID_MAX);
            if(idMaxTmp == -1){
                bookIdMax = 0;
            }else {
                bookIdMax = idMaxTmp;
            }
        }catch (IOException e){
            throw new RuntimeException();
        }
    }

    public void storeMaxBookId(){
        try {
            analyzingBookIdMax.storeBookIdMax(bookIdMax, Constant.BOOK_ID_MAX);
        }catch (IOException e){
            throw new RuntimeException();
        }

    }

    public void loadBooks(){
        try {
            Book[] allBook = analyzingBook.loadAllBook(Constant.ALL_BOOK_FILE_NAME);
            int useBooksCount = 0;
            books = new Book[Constant.CAPACITY];
            if(allBook == null){
                bookCount = 0;
            }else {
                for (int i = 0; i < allBook.length; i++) {
                    if(allBook[i] != null){
                        useBooksCount++;
                    }
                }
            }

            if(useBooksCount > Constant.CAPACITY){
                books = new Book[useBooksCount];
            }

            for (int i = 0; i < useBooksCount; i++) {
                books[i] = allBook[i];
            }

            bookCount = useBooksCount;

        }catch (IOException e){
            throw new RuntimeException();
        }
    }

    public void storeBooks(){
        try {
            analyzingBook.storeAllBook(books, Constant.ALL_BOOK_FILE_NAME);
        }catch (IOException e){
            throw new RuntimeException();
        }
    }

    public static Library getInstance() {
        if (library == null){
            library = new Library();
        }
        return library;
    }

    // 共用的功能

    public void searchBook() {
        boolean flg = false;
        System.out.println("请输入您要查找的书名:");
        String title = scanner.nextLine();
        for (int i = 0; i < bookCount; i++) {
            if(title.equals(books[i].getTitle())){
                flg = true;
                System.out.println(books[i]);
            }
        }
        if(!flg){
            System.out.println("图书管没有你要找的书籍");
        }
    }

    public void dispalyBook() {
        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            System.out.println(book);
        }
    }

    public void exit() {
        System.out.println("退出系统");
        System.exit(0);
    }

    // 管理员的功能

    public void addBook(Book book) {
        System.out.println("library的addBook执行了");
        if(bookCount >= books.length){
            books = Arrays.copyOf(books, books.length*2);
            System.out.println("扩容成功!");
        }

        loadMaxBookId();
        if(bookIdMax == 0){
            book.setId(1);
        }else {
            book.setId(bookIdMax+1);
            bookIdMax = book.getId();
            storeMaxBookId();
        }
        books[bookCount] = book;
        increaseBookCount();
        storeBooks();
        System.out.println("添加书籍成功!");
    }

    public void updateBook(Book book) {
        System.out.println("library的updateBook执行了");
        int bookIndex = searchIndexByBookId(book.getId());
        books[bookIndex] = book;

        storeBooks();
        System.out.println("更新书籍成功");
    }

    public void removeBook(Book book) {
        System.out.println("library的removeBook执行了");
        int bookIndex = searchIndexByBookId(book.getId());

        for (int i = bookIndex; i < bookCount-1; i++) {
            books[i] = books[i+1];
        }
        books[bookCount-1] = null;
        decreaseBookCount();

        storeBooks();
    }

    public void checkAndRemoveOldBook() {
        System.out.println("library的checkAndRemoveOldBook执行了");
        long currentTimeStamp = System.currentTimeMillis();
        LocalDate currentDate = Instant.ofEpochMilli(currentTimeStamp).atZone(ZoneId.systemDefault()).toLocalDate();
        boolean flg = false;
        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];

            // 获取当前书籍的上架时间
            LocalDate shelfDate = book.getShelfDate();

            // 计算两个日期之间的差值
            long yearsBetween = ChronoUnit.YEARS.between(shelfDate, currentDate);
            if(yearsBetween >= 1){
                flg = true;
                System.out.println("图书: " + book.getTitle() + " 已经上架超过一年, 是否移除(y/n)");
                String ret = scanner.nextLine();
                if(ret.equalsIgnoreCase("y")){
                    removeBook(book);
                    i--;
                }
            }
        }

        if(!flg){
            System.out.println("图书管没有超过一年的书籍!");
        }
    }

    public void checkInvertoryStatus() {
        System.out.println("library的checkInvertoryStatus执行了");
        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            String status = book.getIsBorrowed() ? "已借出" : "未借出";
            System.out.println("书名: " + book.getTitle() + ", 借阅状态: " + status);
        }
    }

    public void generateBook(int k) {
        if(books == null){
            return;
        }
        System.out.println("library的generateBook执行了");
        Book[] booksTmp = Arrays.copyOf(books, bookCount);
        Arrays.sort(booksTmp);

        Book[] booksGK = new Book[k];
        for (int i = 0; i < k; i++) {
            booksGK[i] = booksTmp[i];
        }

        System.out.println("最受欢迎的 "+k+" 本书: ");
        for (int i = 0; i < booksGK.length; i++) {
            System.out.println("书名: "+booksGK[i].getTitle() + ", 作者: " + booksGK[i].getAuthor() + ", 借阅次数: " + booksGK[i].getBorrowedCount());
        }

    }

    public void BorrowedCount() {
        if(books == null){
            return;
        }

        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            System.out.println("图书: " + book.getTitle() + ", 借阅次数: " + book.getBorrowedCount());
        }
    }

    private int searchIndexByBookId(int bookId) {
        for (int i = 0; i < bookCount; i++) {
            if(books[i].getId() == bookId){
                return i;
            }
        }
        return -1;
    }

    // 普通用户的功能

    public void borrowedBook(Book book) {
        System.out.println("library的BorrowedBook执行了");
        book.setIsBorrowed(true);
        book.setBorrowedCount(1);
        storeBooks();

        System.out.println("借阅成功!");
    }

    public Book searchBookByBid(int bookId) {
        for (int i = 0; i < bookCount; i++) {
            Book book = books[i];
            if(book.getId() == bookId){
                return book;
            }
        }
        return null;
    }

    public void returnBook(Book book) {
        System.out.println("library的returnBook执行了");
        book.setBorrowedCount(0);
        book.setIsBorrowed(false);
        storeBooks();
        System.out.println("归还成功!");
    }

    public void loadUidAndBookId(){
        try {
            pairOfUidAndBookIds = analyzingBorrowedBook.loadUserIDAndBookId(Constant.BORROWED_BOOK_UID_BOOK_ID);
            int useLen = 0;
            for (int i = 0; i < pairOfUidAndBookIds.length; i++) {
                if(pairOfUidAndBookIds[i] != null){
                    useLen++;
                }
            }
            borrowCount = useLen;
        }catch (IOException e){
            throw new RuntimeException();
        }
    }

    public void storeUidAndBookId(){
        try {
            analyzingBorrowedBook.storeUserIDAndBookId(pairOfUidAndBookIds, Constant.BORROWED_BOOK_UID_BOOK_ID);
        }catch (IOException e){
            throw new RuntimeException();
        }
    }
}
